<template>
  <ClientOnly>
    <p text="sm" v-html="decodedDescription" />
    <div class="example">
      <example :file="path" :demo="formatPathDemos[path]" />
      <el-divider class="divider" />
      <div class="op-btns">
        <el-tooltip :content="locale['edit-on-github']" :show-arrow="false">
          <ElIcon :size="16" class="op-btn github" style="color: var(--text-color-light)">
            <a :href="demoSourceUrl" rel="noreferrer noopener" target="_blank">
              <icon icon="ri:github-line" />
            </a>
          </ElIcon>
        </el-tooltip>
        <el-tooltip :content="locale['copy-code']" :show-arrow="false">
          <ElIcon :size="16" class="op-btn" @click="copyCode">
            <icon icon="ri:file-copy-line" />
          </ElIcon>
        </el-tooltip>
        <el-tooltip :content="locale['view-source']" :show-arrow="false">
          <ElIcon :size="16" class="op-btn" @click="toggleSourceVisible()">
            <icon icon="ri:code-line" />
          </ElIcon>
        </el-tooltip>
      </div>
    </div>
  </ClientOnly>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, toRef } from 'vue';
import { useData } from 'vitepress';
import { isClient, useClipboard, useToggle } from '@vueuse/core';
import { Icon } from '@iconify/vue';
import Example from './Example.vue';
import { createGitHubUrl } from '../../utils';
import demoBlock from '../../../config/demo-block.json';

type DemoType = {
  [key: string]: {
    default: object;
  };
};

const props = defineProps<{
  demos: DemoType;
  source: string;
  path: string;
  rawSource: string;
  description?: string;
}>();

const { theme } = useData();

const vm = getCurrentInstance()!;

const { copy, isSupported } = useClipboard({
  source: decodeURIComponent(props.rawSource),
  read: false,
});

const [sourceVisible, toggleSourceVisible] = useToggle();

const decodedDescription = computed(() => decodeURIComponent(props.description!));

const formatPathDemos = computed(() => {
  const demos: Record<string, object> = {};

  Object.keys(props.demos).forEach((key) => {
    demos[key.replace('../examples/', '').replace('.vue', '')] = props.demos[key].default;
  });

  return demos;
});

const locale = computed(() => demoBlock);
const demoSourceUrl = computed(() => {
  const { repo, docsDir = '', docsBranch = 'dev', docsRepo = repo } = theme.value;

  return createGitHubUrl(docsRepo, docsDir, docsBranch, props.path);
}); //useSourceCode(toRef(props, 'path'))

const copyCode = async () => {
  const { $message } = vm.appContext.config.globalProperties;
  if (!isSupported) {
    $message.error(locale.value['copy-error']);
  }
  try {
    await copy();
    $message.success(locale.value['copy-success']);
  } catch (e: any) {
    $message.error(e.message);
  }
};
</script>

<style scoped lang="scss">
.example {
  @apply border border-gray-300 rounded;
  .divider {
    @apply my-0;
  }
  .op-btns {
    @apply p-1.2 flex items-center justify-end h-8;
    .op-btn {
      @apply mx-2 my-0 cursor-pointer;
      color: var(--el-text-color-secondary);
      transition: 0.2s;
      &:hover {
        color: var(--el-text-color-regular);
      }
      a {
        color: var(--el-text-color-secondary);
        &:hover {
          color: var(--el-text-color-regular);
        }
      }
    }
  }
}
</style>
